home *** CD-ROM | disk | FTP | other *** search
/ Super PC 31 / Super PC 31 (Shareware).iso / spc / inter / speakf / fuente / lwl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-22  |  28.5 KB  |  877 lines

  1. /*
  2.  
  3.     Look Who's Listening dialogue handlers
  4.  
  5. */
  6.  
  7. #include "netfone.h"
  8.  
  9. struct sockaddr_in lookhost;           // Look who's listening host, if any
  10.  
  11. //  EDITRETURN  --  Edit control which notifies parent of return key. 
  12.  
  13. static WNDPROC lpfnOldEdit = NULL;
  14. static DLGPROC editReturnProc = NULL;    // Special edit control procedures
  15.  
  16. #define WM_EDITRETURN    (WM_USER + 1002) 
  17.  
  18. long FAR PASCAL _export editReturn(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  19. {
  20.  
  21.     if (message == WM_GETDLGCODE) {
  22.         return DLGC_WANTALLKEYS;        // We want to see Tab, Return, etc.
  23.     }
  24.  
  25.     if ((message == WM_KEYDOWN && wParam == VK_TAB) ||
  26.         (message == WM_KEYDOWN && wParam == VK_RETURN)) {
  27.         if ((lParam & (1 << 31)) == 0) {
  28.             SendMessage(GetParent(hWnd), WM_COMMAND, GetWindowWord(hWnd, GWW_ID),
  29.                 MAKELONG(hWnd, WM_EDITRETURN));
  30.         }
  31.         return 0L;
  32.     } else {
  33.         return CallWindowProc(lpfnOldEdit, hWnd, message, wParam, lParam);
  34.     }
  35. }
  36.  
  37. /*    SENDLWLMESSAGE    --    If enabled, send a message identifying us
  38.                         to the selected Look Who's Listening server.  */
  39.  
  40. int sendLwlMessage(HWND hDlg, int dobye)
  41. {
  42.     int sock;
  43.  
  44.     sock = socket(AF_INET, SOCK_STREAM, 0);
  45.     if (sock == INVALID_SOCKET) {
  46.         int serr = WSAGetLastError();
  47.                                     
  48.         MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(54),
  49.                 serr, SockerrToString(serr));
  50.         return FALSE;
  51.     }
  52.     if (connect(sock, (struct sockaddr *) &(lookhost), sizeof lookhost) >= 0) {
  53.         if (dobye) {
  54.             char v[128];
  55.             int l;
  56.  
  57.             l = rtp_make_bye(v, ssrc, rstring(IDS_T_RAISON_EXITING));
  58.             if (send(sock, v, l, 0) < 0) {
  59.                 int serr = WSAGetLastError();
  60.                                             
  61.                 MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(55),
  62.                         serr, SockerrToString(serr));
  63.                 closesocket(sock);
  64.                 return FALSE;
  65.             }
  66.         } else {
  67.             if (send(sock, (char *) sdes, sdesl, 0) < 0) {
  68.                 int serr = WSAGetLastError();
  69.                                             
  70.                 MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(56),
  71.                         serr, SockerrToString(serr));
  72.                 closesocket(sock);
  73.                 return FALSE;
  74.             }
  75.         }
  76.     } else {
  77.         int serr = WSAGetLastError();
  78.                                             
  79.         MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(57),
  80.                 serr, SockerrToString(serr));
  81.         closesocket(sock);
  82.         return FALSE;
  83.     }
  84.     closesocket(sock);
  85.     return TRUE;
  86. }
  87.  
  88. //    LWL_RECONNECT  --  Reconnect to current Look Who's Listening server
  89.  
  90. int lwl_reconnect(HWND hDlg)
  91. {
  92.     if (lwl_s_server[0] == 0 || lwl_s_email[0] == 0) {
  93.         lwl_s_publish = FALSE;
  94.     }
  95.                         
  96.     //    Remake SDES information
  97.                     
  98.     if (sdes != NULL) {
  99.         free(sdes);
  100.         sdes = NULL;
  101.     }
  102.     if (lwl_s_email[0] != 0) {
  103.         sdesl = rtp_make_sdes(&sdes, ssrc, lwl_s_exact);
  104.     }
  105.                     
  106.     /*    If the user wishes to publish this information, look
  107.         up the host where it's to be published.  */
  108.                     
  109.     if (lwl_s_publish) {    
  110.         lookhost.sin_family = AF_INET;
  111.         lookhost.sin_port = htons(NETFONE_COMMAND_PORT + 2);
  112.         lookhost.sin_addr.s_addr = inet_addr(lwl_s_server);
  113.         if (lookhost.sin_addr.s_addr == INADDR_NONE) {
  114.             LPHOSTENT h = gethostbyname(lwl_s_server);
  115.                             
  116.             if (h == NULL) {
  117.                 int serr = WSAGetLastError();
  118.                                     
  119.                 MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(41),
  120.                         (LPSTR) lwl_s_server,
  121.                         serr, SockerrToString(serr));
  122.                 return FALSE;
  123.             } else {
  124.                 _fmemcpy(&lookhost.sin_addr.s_addr, (h->h_addr),
  125.                     sizeof lookhost.sin_addr.s_addr);
  126.             }
  127.         }
  128.         if ((lwl_t_published = sendLwlMessage(hDlg, FALSE)) != FALSE) {
  129.             lwl_t_resend = TIMEOUT_RESEND_LWL;    // Set resend timer
  130.         }                        
  131.     }
  132.     return TRUE;
  133. }
  134.  
  135. //    LWL_TELL_PROC  --  Look Who's Listening publish dialogue procedure
  136.  
  137. BOOL CALLBACK lwl_tell_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  138. {
  139.     static int serverDefault;
  140.  
  141.     switch (message) {
  142.         case WM_INITDIALOG:
  143.             {
  144.                 CheckDlgButton(hDlg, IDC_LWLS_UNLISTED, lwl_s_publish);
  145.                 CheckDlgButton(hDlg, IDC_LWLS_EXACT, lwl_s_exact);
  146.                 if ((serverDefault = (lwl_s_server[0] == 0)) != 0) {
  147.                     SetDlgItemText(hDlg, IDC_LWLS_SERVER, rstring(IDS_T_LWL_DEFAULT_SERVER));
  148.                 } else {
  149.                     SetDlgItemText(hDlg, IDC_LWLS_SERVER, lwl_s_server);
  150.                 }
  151.                 SetDlgItemText(hDlg, IDC_LWLS_EMAIL, lwl_s_email);
  152.                 SetDlgItemText(hDlg, IDC_LWLS_FULLNAME, lwl_s_fullname);
  153.                 SetDlgItemText(hDlg, IDC_LWLS_PHONE, lwl_s_phone);
  154.                 SetDlgItemText(hDlg, IDC_LWLS_LOCATION, lwl_s_location);
  155.             }
  156.             break;
  157.  
  158.         case WM_COMMAND:
  159.             switch ((int) wParam) {
  160.                 case IDOK:
  161.                 
  162.                     /* If information is currently published, revoke it in
  163.                        case we're about to publish a changed version. */
  164.                        
  165.                     if (lwl_t_published) {
  166.                         sendLwlMessage(hDlg, TRUE);        // Send BYE message
  167.                         lwl_t_published = FALSE;
  168.                     }
  169.                 
  170.                     lwl_s_publish = IsDlgButtonChecked(hDlg, IDC_LWLS_UNLISTED);
  171.                     lwl_s_exact = IsDlgButtonChecked(hDlg, IDC_LWLS_EXACT);
  172.                     if (!serverDefault) {
  173.                         GetDlgItemText(hDlg, IDC_LWLS_SERVER, lwl_s_server, sizeof lwl_s_server);
  174.                     }
  175.                     GetDlgItemText(hDlg, IDC_LWLS_EMAIL, lwl_s_email, sizeof lwl_s_email);
  176.                     GetDlgItemText(hDlg, IDC_LWLS_FULLNAME, lwl_s_fullname, sizeof lwl_s_fullname);
  177.                     GetDlgItemText(hDlg, IDC_LWLS_PHONE, lwl_s_phone, sizeof lwl_s_phone);
  178.                     GetDlgItemText(hDlg, IDC_LWLS_LOCATION, lwl_s_location, sizeof lwl_s_location);
  179.                     if (lwl_reconnect(hDlg)) {
  180.                         EndDialog(hDlg, TRUE);
  181.                     }
  182.                     break;
  183.  
  184.                 case IDCANCEL:
  185. //                    WSACancelBlockingCall();        // Cancel any in-progress request
  186.                     EndDialog(hDlg, FALSE);
  187.                     break;
  188.                     
  189.                 case IDC_LWLS_SERVER:
  190.                     if (HIWORD(lParam) == EN_CHANGE) {
  191.                         serverDefault = FALSE;
  192.                     }
  193.                     break;
  194.                     
  195.                 case ID_HELP:
  196.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  197.                                 ((DWORD) (Lrstring(IDS_HELP_LWL_TELL))));
  198.                     holped = TRUE;
  199.                     break;
  200.  
  201.                 default:
  202.                     break;
  203.             }
  204.             break;
  205.             
  206.         default:
  207.             break;            
  208.     }
  209.     return FALSE;
  210. }
  211.  
  212. //    LWL_TELL_SETTINGS  --  Set Look Who's Listening published properties
  213.  
  214. VOID lwl_tell_settings(HWND hwnd)
  215. {
  216.     FARPROC pfnDlg;
  217.  
  218.     pfnDlg = MakeProcInstance((FARPROC) lwl_tell_proc, hInst);
  219.     DialogBox(hInst, MAKEINTRESOURCE(IDD_LWL_TELL), hwnd, (DLGPROC) pfnDlg);
  220.     FreeProcInstance(pfnDlg);
  221.     return;
  222. }
  223.  
  224. struct lwl {
  225.     struct lwl FAR *next;                // Next connection
  226.     long ltime;                            // Time of last update
  227.     unsigned long ssrc;                    // Session source descriptor
  228.     long naddr;                            // Internet address
  229.     short port;                            // Port address
  230.     LPSTR cname;                        // Canonical name 
  231.     LPSTR name;                            // User name
  232.     LPSTR email;                        // Electronic mail address
  233.     LPSTR phone;                        // Telephone number
  234.     LPSTR loc;                            // Geographic location
  235.     LPSTR tool;                            // Application name
  236. };
  237.  
  238. static struct lwl FAR *conn;            // Connection chain
  239. static struct lwl FAR *ctail;            // Connection chain tail
  240. static int diasel = -1;                    // Selected item in results box
  241.  
  242. /*    DUPSDESITEM  --  Make a copy of an SDES item and advance the pointer
  243.                      past it.  */
  244.  
  245. static LPSTR dupSdesItem(char **cp)
  246. {
  247.     char *ip = *cp;
  248.     int l = ip[1];
  249.     LPSTR bp;
  250.  
  251.     bp = GlobalAllocPtr(GPTR, l + 1);
  252.     if (bp != NULL) {
  253.         _fmemcpy(bp, ip + 2, l);
  254.         bp[l] = 0;
  255.     }
  256.     *cp = ip + l + 2;
  257.     return bp;
  258. }
  259.  
  260. //    DESTROYLWL    --    Release storage associated with an LWL list item.
  261.  
  262. static void destroyLwl(struct lwl FAR *lw)
  263. {
  264.     if (lw->cname != NULL) {
  265.         GlobalFreePtr(lw->cname);
  266.     }
  267.     if (lw->name != NULL) {
  268.         GlobalFreePtr(lw->name);
  269.     }
  270.     if (lw->email != NULL) {
  271.         GlobalFreePtr(lw->email);
  272.     }
  273.     if (lw->phone != NULL) {
  274.         GlobalFreePtr(lw->phone);
  275.     }
  276.     if (lw->loc != NULL) {
  277.         GlobalFreePtr(lw->loc);
  278.     }
  279.     if (lw->tool != NULL) {
  280.         GlobalFreePtr(lw->tool);
  281.     }
  282.     GlobalFreePtr(lw);
  283. }
  284.  
  285. //    FREELWLCHAIN  --  Release all items in LWL chain
  286.  
  287. static void freeLwlChain(void)
  288. {
  289.     while (conn != NULL) {
  290.         struct lwl FAR *co = conn;
  291.         
  292.         conn = co->next;
  293.         destroyLwl(co);
  294.     }
  295. }
  296.  
  297. //    LWLITEM  --  Get LWL chain item by zero-based index
  298.  
  299. static struct lwl FAR *lwlItem(int i)
  300. {
  301.     struct lwl FAR *co = conn;
  302.  
  303.     while (co != NULL && i-- > 0) {
  304.         co = co->next;
  305.     }
  306.     return co;
  307. }
  308.  
  309. //  ENABLE_ASK_INPUTS  --  Enable/Disable Look Who's Listening query requests
  310.  
  311. static void enable_ask_inputs(HWND hDlg, int enable)
  312. {
  313. #define EnableD(x) EnableWindow(GetDlgItem(hDlg, x), enable)
  314.     EnableD(IDC_LWLA_SERVER);
  315.     EnableD(IDC_LWLA_QUERY);
  316.     EnableD(IDC_LWLA_SEARCH);
  317.     EnableD(IDOK);
  318. }
  319.  
  320. #define nTextItems    5
  321.  
  322. //    UPDATESERVERMESSAGE  --  Update server message on initial connect or server change
  323.  
  324. static void updateServerMessage(HWND hDlg)
  325. {
  326.     struct sockaddr_in askhost;
  327.     char sv[512];
  328.     char *serv = sv, *cp;
  329.     rtcp_t *rp = (rtcp_t *) sv;
  330.     SOCKET sock;
  331.     int l;
  332.  
  333.     enable_ask_inputs(hDlg, FALSE);                        
  334.     GetDlgItemText(hDlg, IDC_LWLA_SERVER, sv, sizeof sv);
  335.     if (sv[0] == '(') {
  336.         serv++;
  337.         if ((cp = strchr(serv, ')')) != NULL) {
  338.             *cp = 0;
  339.         }
  340.     }
  341.     askhost.sin_family = AF_INET;
  342.     askhost.sin_port = htons(NETFONE_COMMAND_PORT + 2);
  343.     askhost.sin_addr.s_addr = inet_addr(serv);
  344.     if (askhost.sin_addr.s_addr == INADDR_NONE) {
  345.         LPHOSTENT h;
  346.  
  347.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  348.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  349.                             (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_LOOKUP));
  350.         h = gethostbyname(serv);
  351.         if (h == NULL) {
  352.             int serr = WSAGetLastError();
  353.             
  354.             if (serr != WSAEINTR) {                                        
  355.                 MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(41),
  356.                         (LPSTR) serv,
  357.                         serr, SockerrToString(serr));
  358.             }
  359.             SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  360.             enable_ask_inputs(hDlg, TRUE);                        
  361.             return;
  362.         } else {
  363.             _fmemcpy(&askhost.sin_addr.s_addr, (h->h_addr),
  364.                 sizeof askhost.sin_addr.s_addr);
  365.         }
  366.     }
  367.  
  368.     // Create the socket and connect to host
  369.                 
  370.     SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  371.                         (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_CONNECT));
  372.     sock = socket(AF_INET, SOCK_STREAM, 0);
  373.     if (sock == INVALID_SOCKET) {
  374.         int serr = WSAGetLastError();
  375.                                                         
  376.         MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(54),
  377.                 serr, SockerrToString(serr));
  378.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  379.         enable_ask_inputs(hDlg, TRUE);                        
  380.         return;
  381.     }
  382.                 
  383.     if (connect(sock, (struct sockaddr *) &askhost, sizeof askhost) < 0) {
  384.         int serr = WSAGetLastError();
  385.                                                                 
  386.         MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(57),
  387.                 serr, SockerrToString(serr));
  388.         closesocket(sock);
  389.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  390.         enable_ask_inputs(hDlg, TRUE);                        
  391.         return;
  392.     }
  393.     *((short *) sv) = (RTP_VERSION << 14) | RTCP_APP | (1 << 8);
  394.     rp->r.sdes.src = 0;
  395.     _fmemcpy(sv + 8, rstring(IDS_T_LWL_GETMESSAGE), 4);
  396.     *((short *) (sv + 2)) = 2;    // Message length in 32 bit words - 1
  397.     revshort((short *) sv);
  398.     revshort((short *) (sv + 2));
  399.     SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  400.                         (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_REQUEST));
  401.     if (send(sock, sv, 12, 0) < 0) {
  402.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  403.         enable_ask_inputs(hDlg, TRUE);                        
  404.         return;
  405.     }
  406.     SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  407.                             (LPARAM) (LPCSTR) rstring(IDS_T_RECEIVE));
  408.     if ((l = recv(sock, sv, sizeof sv, 0)) <= 0) {
  409.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  410.         enable_ask_inputs(hDlg, TRUE);                        
  411.         return;
  412.     }
  413.     closesocket(sock);            // Don't need socket any more
  414.     
  415.     SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  416.     diasel = -1;
  417.     freeLwlChain();
  418.     cp = sv + 12;
  419.     while (cp != NULL) {
  420.         char *np = strchr(cp, '\n');
  421.                         
  422.         if (np != NULL) {
  423.             *np++ = 0;
  424.         }
  425.         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  426.                             (LPARAM) (LPCSTR) cp);
  427.         cp = np;
  428.     }
  429.     enable_ask_inputs(hDlg, TRUE);                        
  430. }
  431.  
  432. //    LWL_ASK_PROC  --  Look Who's Listening search dialogue procedure
  433.  
  434. BOOL CALLBACK lwl_ask_proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  435. {
  436.     static int echanged;
  437.     int i;
  438.  
  439.     switch (message) {
  440.         case WM_INITDIALOG:
  441.             {
  442.                 CheckDlgButton(hDlg, IDC_LWLA_EXACT, lwl_a_exact);
  443.                 /*    If no Ask server is specified, use the Tell server
  444.                     (or the default for it).  */ 
  445.                 if (lwl_a_server[0] == 0) {
  446.                     char as[82];
  447.                     
  448.                     if (lwl_s_server[0] == 0) {
  449.                         wsprintf(as, Format(61), (LPSTR) rstring(IDS_T_LWL_DEFAULT_SERVER));
  450.                     } else {
  451.                         wsprintf(as, Format(61), (LPSTR) lwl_s_server);
  452.                     }
  453.                     SetDlgItemText(hDlg, IDC_LWLA_SERVER, as);
  454.                 } else {
  455.                     SetDlgItemText(hDlg, IDC_LWLA_SERVER, lwl_a_server);
  456.                 }
  457.                 diasel = -1;
  458.                 
  459.                 //    Subclass edit controls to permit automatic update when they change
  460.                 
  461.                 if (editReturnProc == NULL) {
  462.                     editReturnProc = (DLGPROC) MakeProcInstance((FARPROC) editReturn, hInst);
  463.                 }
  464.                 lpfnOldEdit = (WNDPROC) GetWindowLong(GetDlgItem(hDlg, IDC_LWLA_SERVER),
  465.                                             GWL_WNDPROC);
  466.                 SetWindowLong(GetDlgItem(hDlg, IDC_LWLA_SERVER), GWL_WNDPROC,
  467.                                             (LONG) editReturnProc);
  468.                 SetWindowLong(GetDlgItem(hDlg, IDC_LWLA_QUERY), GWL_WNDPROC,
  469.                                             (LONG) editReturnProc);
  470.  
  471.                 EnableWindow(GetDlgItem(hDlg, IDC_LWLA_CONNECT), FALSE);
  472.                 conn = NULL;
  473.                 updateServerMessage(hDlg);
  474.             }
  475.             break;
  476.             
  477. /*         
  478.         case WM_DESTROY:
  479.             Nopey, nopey, no.  You see, this is called *before* the child windows
  480.             are destroyed, so if you nuke the WindowsProctologyInterface here
  481.             you suck wind when the child window calls the already deleted subclass
  482.             procedure.  But, not to worry (after 35 reboots and 8 hours of futile
  483.             flailing), the ProcInstance lives in your local data segment, so there's no
  484.             reason to release it.  We therefore create it the first time the Search
  485.             dialogue is invoked, and reuse the preexisting instance on subsequent
  486.             invocations, deferring its ultimate Destruction to the Creator who, in
  487.             in a moment of folly said, "Let Windows Be".
  488.  
  489.             if (editReturnProc != NULL) {
  490.                 FreeProcInstance((FARPROC) editReturnProc);
  491.                 editReturnProc = NULL;
  492.             }
  493.             break;
  494. */            
  495.  
  496.         case WM_COMMAND:
  497.             switch ((int) wParam) {
  498.                 case IDOK:
  499.                     {
  500.                         char *serv = lwl_a_server;
  501.                     
  502.                         lwl_a_exact = IsDlgButtonChecked(hDlg, IDC_LWLA_EXACT);
  503.                         GetDlgItemText(hDlg, IDC_LWLA_SERVER, lwl_a_server, sizeof lwl_a_server);
  504.                         if (lwl_a_server[0] == '(') {
  505.                             lwl_a_server[0] = 0;
  506.                         }
  507.                         freeLwlChain();
  508.                         EndDialog(hDlg, TRUE);
  509.                     }
  510.                     break;
  511.  
  512.                 case IDCANCEL:
  513.                     freeLwlChain();
  514. //                    WSACancelBlockingCall();        // Cancel any in-progress request
  515.                     EndDialog(hDlg, FALSE);
  516.                     break;
  517.                     
  518.                 case IDC_LWLA_SERVER:
  519.                     if (HIWORD(lParam) == EN_SETFOCUS) {
  520.                         echanged = FALSE;
  521.                     } else if (HIWORD(lParam) == EN_CHANGE) {
  522.                         echanged = TRUE;
  523.                     } else if (((HIWORD(lParam) == WM_EDITRETURN) ||
  524.                                ((HIWORD(lParam) == EN_KILLFOCUS) && echanged))) {
  525.                         echanged = FALSE;
  526.                         //    Get server welcome message, if any, and display
  527.                         updateServerMessage(hDlg);
  528.                     }
  529.                     break;                    
  530.                     
  531.                 case IDC_LWLA_QUERY:
  532.                     if (HIWORD(lParam) == EN_SETFOCUS) {
  533.                         echanged = FALSE;
  534.                     } else if (HIWORD(lParam) == EN_CHANGE) {
  535.                         echanged = TRUE;
  536.                     } else if (((HIWORD(lParam) == WM_EDITRETURN) ||
  537.                                ((HIWORD(lParam) == EN_KILLFOCUS) && echanged))) {
  538.                         char qs[256];
  539.                         
  540.                         GetDlgItemText(hDlg, IDC_LWLA_QUERY, qs, sizeof qs);
  541.                         if (_fstrlen(qs) > 0) {
  542.                             GetDlgItemText(hDlg, IDC_LWLA_SERVER, qs, sizeof qs);
  543.                             if (_fstrlen(qs) > 0) {
  544.                                 PostMessage(hDlg, WM_COMMAND, IDC_LWLA_SEARCH, 0L);
  545.                             }
  546.                         }
  547.                         echanged = FALSE;
  548.                     }
  549.                     break;                    
  550.                     
  551.                 case IDC_LWLA_CONNECT:
  552.                     if (diasel >= 0) {
  553.                         struct lwl FAR *l = lwlItem(diasel);
  554.                         
  555.                         if (l != NULL) {
  556.                             struct sockaddr_in u;
  557.                             
  558.                             u.sin_addr.s_addr = l->naddr;
  559.                             newConnection(hwndMDIFrame, NULL, inet_ntoa(u.sin_addr));
  560.                             PostMessage(hDlg, WM_COMMAND, IDOK, 0L);
  561.                         }
  562.                     }
  563.                     break;
  564.                     
  565.                 case IDC_LWLA_RESULTS:
  566.                     for (i = 0; i < nTextItems; i++) {
  567.                         SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i, "");
  568.                     }
  569.                     if (HIWORD(lParam) == LBN_SELCHANGE) {
  570.                         /*    Allow selection in results box only if it shows
  571.                             result from a query as opposed to a server message. */
  572.                         if (conn == NULL) {
  573.                             diasel = LB_ERR;
  574.                             SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS,
  575.                                         LB_SETCURSEL, (WPARAM) -1, 0L);
  576.                         } else {
  577.                             diasel = (int) SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS,
  578.                                         LB_GETCURSEL, 0, 0L);
  579.                         }
  580.                         if (diasel == LB_ERR) {
  581.                             diasel = -1;
  582.                         } 
  583.                     } else if (HIWORD(lParam) == LBN_SELCANCEL) {
  584.                         diasel = -1;
  585.                     }
  586.                     EnableWindow(GetDlgItem(hDlg, IDC_LWLA_CONNECT), diasel >= 0);
  587.                     if (diasel >= 0) {
  588.                         struct lwl FAR *l = lwlItem(diasel);
  589.                         
  590.                         if (l != NULL) {
  591.                             char eb[40];
  592.                             struct sockaddr_in u;
  593.                             
  594.                             i = 0;
  595.                             if (l->name != NULL) {
  596.                                 SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i++, l->name);     
  597.                             }
  598.                             SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i++, l->email ?
  599.                                 l->email : l->cname);
  600.                             if (l->loc != NULL) {
  601.                                 SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i++, l->loc);     
  602.                             }
  603.                             if (l->phone != NULL) {
  604.                                 SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i++, l->phone);     
  605.                             }
  606.                             u.sin_addr.s_addr = l->naddr;
  607.                             _fstrcpy(eb, inet_ntoa(u.sin_addr));
  608.                             wsprintf(eb + strlen(eb), Format(64), l->port);
  609.                             SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i++, eb);      
  610.                         }
  611.                     } 
  612.                     break;
  613.                     
  614.                 case IDC_LWLA_SEARCH:
  615.                     {
  616.                         struct sockaddr_in askhost;
  617.                         char sv[512];
  618.                         char *serv = sv, *cp;
  619.                         rtcp_t *rp = (rtcp_t *) sv;
  620.                         SOCKET sock;
  621.                         int l, nitems;
  622.                         
  623.                         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  624.                         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  625.                             (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_LOOKUP));
  626.                         GetDlgItemText(hDlg, IDC_LWLA_SERVER, sv, sizeof sv);
  627.                         if (sv[0] == '(') {
  628.                             serv++;
  629.                             if ((cp = strchr(serv, ')')) != NULL) {
  630.                                 *cp = 0;
  631.                             }
  632.                         }
  633.                         askhost.sin_family = AF_INET;
  634.                         askhost.sin_port = htons(NETFONE_COMMAND_PORT + 2);
  635.                         askhost.sin_addr.s_addr = inet_addr(serv);
  636.                         enable_ask_inputs(hDlg, FALSE);
  637.                         if (askhost.sin_addr.s_addr == INADDR_NONE) {
  638.                             LPHOSTENT h = gethostbyname(serv);
  639.                                             
  640.                             if (h == NULL) {
  641.                                 int serr = WSAGetLastError();
  642.                                 
  643.                                 if (serr != WSAEINTR) {                    
  644.                                     MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(41),
  645.                                             (LPSTR) serv,
  646.                                             serr, SockerrToString(serr));
  647.                                 }
  648.                                 SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  649.                                 enable_ask_inputs(hDlg, TRUE);
  650.                                 break;
  651.                             } else {
  652.                                 _fmemcpy(&askhost.sin_addr.s_addr, (h->h_addr),
  653.                                     sizeof askhost.sin_addr.s_addr);
  654.                             }
  655.                         }
  656.  
  657.                         // Create the socket and connect to host
  658.                 
  659.                         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  660.                             (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_CONNECT));
  661.                         sock = socket(AF_INET, SOCK_STREAM, 0);
  662.                         if (sock == INVALID_SOCKET) {
  663.                             int serr = WSAGetLastError();
  664.                                                         
  665.                             MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(54),
  666.                                     serr, SockerrToString(serr));
  667.                             SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  668.                             enable_ask_inputs(hDlg, TRUE);
  669.                             break;
  670.                         }
  671.                 
  672.                         if (connect(sock, (struct sockaddr *) &askhost, sizeof askhost) < 0) {
  673.                             int serr = WSAGetLastError();
  674.                                                                 
  675.                             MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(57),
  676.                                     serr, SockerrToString(serr));
  677.                             closesocket(sock);
  678.                             SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  679.                             enable_ask_inputs(hDlg, TRUE);
  680.                             break;
  681.                         }
  682.                         *((short *) sv) = (RTP_VERSION << 14) | RTCP_APP | (1 << 8);
  683.                         rp->r.sdes.src = 0;
  684.                         _fmemcpy(sv + 8, rstring(IDS_T_LWL_QUERY), 4);
  685.                         cp = sv + 12;
  686.                         if (IsDlgButtonChecked(hDlg, IDC_LWLA_EXACT)) {
  687.                             *cp++ = '*';
  688.                         }
  689.                         GetDlgItemText(hDlg, IDC_LWLA_QUERY, cp, (sizeof sv) - (cp - sv));
  690.                         cp += strlen(cp) + 1;
  691.                         while ((cp - sv) & 3) {
  692.                             *cp++ = 0;
  693.                         }
  694.                         *((short *) (sv + 2)) = ((cp - sv) / 4) - 1;
  695.                         revshort((short *) sv);
  696.                         revshort((short *) (sv + 2));
  697.                         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  698.                             (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_QUERY));
  699.                         if (send(sock, sv, 13 + strlen(sv + 12), 0) < 0) {
  700.                             int serr = WSAGetLastError();
  701.                                                                 
  702.                             MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(62),
  703.                                     serr, SockerrToString(serr));
  704.                             closesocket(sock);
  705.                             SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  706.                             enable_ask_inputs(hDlg, TRUE);
  707.                             break;
  708.                         }
  709.                         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  710.                             (LPARAM) (LPCSTR) rstring(IDS_T_LWLA_RESULTS));
  711.                         if ((l = recv(sock, sv, sizeof sv, 0)) <= 0) {
  712.                             int serr = WSAGetLastError();
  713.                                                                 
  714.                             MsgBox(hDlg, MB_ICONSTOP | MB_OK, Format(63),
  715.                                     serr, SockerrToString(serr));
  716.                             closesocket(sock);
  717.                             SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  718.                             enable_ask_inputs(hDlg, TRUE);
  719.                             break;
  720.                         }
  721.                         closesocket(sock);            // Don't need socket any more
  722.                         
  723.                         enable_ask_inputs(hDlg, TRUE);
  724.                         nitems = sv[0] & 0x1F;
  725.                         SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_RESETCONTENT, 0, 0L);
  726.                         freeLwlChain();                // Release any previous results
  727.                         diasel = -1;
  728.                         for (i = 0; i < nTextItems; i++) {
  729.                             SetDlgItemText(hDlg, IDC_LWLA_LINE1 + i, "");
  730.                         }
  731.                         EnableWindow(GetDlgItem(hDlg, IDC_LWLA_CONNECT), FALSE);
  732.                         cp = (char *) &(rp->r.sdes.src);
  733.                         while (nitems-- > 0) {
  734.                             struct lwl FAR *lw;
  735.             
  736.                             lw = (struct lwl FAR *) GlobalAllocPtr(GPTR, sizeof(struct lwl));
  737.                             if (lw != NULL) {
  738.                                 int parsing = TRUE;
  739.                                 struct sockaddr_in u;
  740.             
  741.                                 _fmemcpy(&(lw->ssrc), cp, 4);
  742.                                 cp += 4;
  743.             
  744.                                 while (parsing) {
  745.                                     switch (*cp) {
  746.             
  747.                                         case RTCP_SDES_CNAME:        // Canonical (talk, finger) name
  748.                                             lw->cname = dupSdesItem(&cp);
  749.                                             break;
  750.             
  751.                                         case RTCP_SDES_NAME:        // Full name
  752.                                             lw->name = dupSdesItem(&cp);
  753.                                             break;
  754.             
  755.                                         case RTCP_SDES_EMAIL:        // E-mail address
  756.                                             lw->email = dupSdesItem(&cp);
  757.                                             break;
  758.             
  759.                                         case RTCP_SDES_PHONE:        // Telephone number
  760.                                             lw->phone = dupSdesItem(&cp);
  761.                                             break;
  762.             
  763.                                         case RTCP_SDES_LOC:            // Geographical location
  764.                                             lw->loc = dupSdesItem(&cp);
  765.                                             break;
  766.             
  767.                                         case RTCP_SDES_TOOL:        // Tool (client) name
  768.                                             lw->tool = dupSdesItem(&cp);
  769.                                             break;
  770.             
  771.                                         case RTCP_SDES_PRIV:        // Private SDES extensions
  772.                                             {
  773.                                                 LPSTR zp = dupSdesItem(&cp);
  774.             
  775.                                                 if (*zp != NULL) {
  776.                                                     char hawx[20];
  777.                                                     
  778.                                                     //    P:    Port user is listening on
  779.                                                     if (zp[0] == 1 &&
  780.                                                         zp[1] == 'P') {
  781.                                                         _fstrcpy(hawx, zp + 2);
  782.                                                         lw->port = atoi(hawx);
  783.                                                         
  784.                                                     //    I:    IP address of user (as long)
  785.                                                     } else if (zp[0] == 1 &&
  786.                                                                zp[1] == 'I') {
  787.                                                         lw->naddr = inet_addr(zp + 2);
  788.                                                         
  789.                                                     //    T:    Time and date of last status update
  790.                                                     }  else if (zp[0] == 1 &&
  791.                                                                 zp[1] == 'T') {
  792.                                                         _fstrcpy(hawx, zp + 2);
  793.                                                         lw->ltime = atol(hawx);
  794.                                                     }
  795.                                                     GlobalFreePtr(zp);
  796.                                                 }
  797.                                             }
  798.                                             break;
  799.             
  800.                                         case RTCP_SDES_END:
  801.                                             cp++;
  802.                                             while ((cp - sv) & 3) {
  803.                                                 cp++;
  804.                                             }
  805.                                             parsing = FALSE;
  806.                                             break;
  807.             
  808.                                         default:
  809.                                             {
  810.                                                 LPSTR zp = dupSdesItem(&cp);
  811.             
  812.                                                 if (zp != NULL) {
  813.                                                     GlobalFreePtr(zp);
  814.                                                 }
  815.                                             }
  816.                                             break;
  817.                                     }
  818.                                 }
  819.                                 u.sin_addr.s_addr = lw->naddr;
  820.  
  821.                                 if (lw->cname != NULL || lw->email != NULL) {
  822.                                     char s[256];
  823.                                     
  824.                                     _fstrcpy(s, lw->email != NULL ? lw->email : lw->cname);
  825.                                     if (lw->name != NULL) {
  826.                                         wsprintf(s + strlen(s), Format(34), lw->name);
  827.                                     }
  828.                                     if (lw->loc != NULL) {
  829.                                         strcat(s, " ");
  830.                                         _fstrcat(s, lw->loc);
  831.                                     }                                 
  832.                                     SendDlgItemMessage(hDlg, IDC_LWLA_RESULTS, LB_ADDSTRING, 0,
  833.                                         (LPARAM) (LPCSTR) s);
  834.                                     lw->next = NULL;
  835.                                     if (conn == NULL) {
  836.                                         conn = ctail = lw;
  837.                                     } else {
  838.                                         ctail->next = lw;
  839.                                         ctail = lw;
  840.                                     }
  841.                                 } else {                                
  842.                                     destroyLwl(lw);
  843.                                 }
  844.                             }
  845.                         }
  846.                     }
  847.                     break;
  848.                     
  849.                 case ID_HELP:
  850.                     WinHelp(hwndMDIFrame, rstring(IDS_HELPFILE), HELP_KEY,
  851.                                 ((DWORD) (Lrstring(IDS_HELP_LWL_ASK))));
  852.                     holped = TRUE;
  853.                     break;
  854.  
  855.                 default:
  856.                     break;
  857.             }
  858.             break;
  859.             
  860.         default:
  861.             break;            
  862.     }
  863.     return FALSE;
  864. }
  865.  
  866. //    LWL_ASK  --  Search Look Who's Listening directory
  867.  
  868. VOID lwl_ask(HWND hwnd)
  869. {
  870.     FARPROC pfnDlg;
  871.  
  872.     pfnDlg = MakeProcInstance((FARPROC) lwl_ask_proc, hInst);
  873.     DialogBox(hInst, MAKEINTRESOURCE(IDD_LWL_ASK), hwnd, (DLGPROC) pfnDlg);
  874.     FreeProcInstance(pfnDlg);
  875.     return;
  876. }
  877.